/**业务管理流程平台版本1.0,生成时间:2017-04-13 13:16:48**/
package com.xbdun.service.bmp.biz.impl;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.xbdun.common.api.Client;
import com.xbdun.common.enums.UserRolesEnums;
import com.xbdun.common.enums.YesOrNoEnum;
import com.xbdun.common.exceptions.BizException;
import com.xbdun.common.page.Pager;
import com.xbdun.common.util.CommonUtil;
import com.xbdun.dao.bmp.dto.AgentOrgDto;
import com.xbdun.dao.bmp.entity.XbdunOrgUserDo;
import com.xbdun.dao.bmp.entity.XbdunSysOrgDo;
import com.xbdun.dao.bmp.entity.XbdunSysUserDo;
import com.xbdun.dao.bmp.mapper.OrgUserMapper;
import com.xbdun.dao.bmp.mapper.SysOrgMapper;
import com.xbdun.dao.bmp.mapper.SysUserMapper;
import com.xbdun.facade.bmp.constant.SysOrgConst;
import com.xbdun.facade.bmp.enumx.SysOrgEnum.SpecilRoleEnum;
import com.xbdun.facade.bmp.enumx.SysOrgEnum.SysOrgAuditingStatusEnum;
import com.xbdun.facade.bmp.enumx.SysOrgEnum.SysOrgEnableEnum;
import com.xbdun.facade.bmp.enumx.SysOrgEnum.SysOrgInvitTypeEnum;
import com.xbdun.facade.bmp.enumx.UserEnum.UserEffectEnum;
import com.xbdun.facade.bmp.enumx.UserEnum.UserEnabledEnum;
import com.xbdun.facade.bmp.enumx.UserEnum.UserInauTypeEnum;
import com.xbdun.facade.bmp.exceptions.BmpBizException;
import com.xbdun.facade.bmp.response.system.SysOrgResponse;
import com.xbdun.service.bmp.biz.OrgUserBiz;
import com.xbdun.service.bmp.biz.SysOrgBiz;
import com.xbdun.service.bmp.service.cache.OrgInfoCacheService;

import lombok.extern.slf4j.Slf4j;


/**
 * 企业信息
 * @ClassName XbdunSysOrgServiceImpl
 * @author 张国涛
 * @2017-04-13 13:16:48
 */
@Service
@Transactional
@Slf4j
public class SysOrgBizImpl implements SysOrgBiz {
	@Autowired
	private SysOrgMapper sysOrgMapper;
	@Autowired
	private SysUserMapper sysUserMapper;
	@Autowired
	private OrgUserMapper orgUserMapper;
	@Autowired
	private OrgUserBiz orgUserBiz;
	@Autowired
	OrgInfoCacheService orgInfoCacheService;
	/**
	 * 根据主键获取对象
	 * @return {@link XbdunSysOrgDo}
	 */
	public XbdunSysOrgDo getSysOrgByOrgCode(long orgCode)throws RuntimeException{
		Assert.isTrue(orgCode>0, "机构编号不能小于零");
		
		return sysOrgMapper.getSysOrgByOrgCode(orgCode);
	}
	
	/**
	 * 新增
	 * @param xbdunSysOrgDo 
	 */
	public Long addXbdunSysOrg(XbdunSysOrgDo xbdunSysOrgDo)throws RuntimeException{
		return sysOrgMapper.addXbdunSysOrg(xbdunSysOrgDo);
	}
	
	/**
	 * 删除数据根据主键
	 * @param idx
	 */
	public void delXbdunSysOrgById(long id)throws RuntimeException{
		Assert.isTrue(id>0, "主键id不能小于零");
		
		sysOrgMapper.delXbdunSysOrgById(id);
		orgInfoCacheService.removeSingleOrgInfo(id);
	}
	
	/**
	 * 更新对象属性
	 * @param XbdunSysOrgDo	更新对象
	 * @param id
	 */
	public void updateOrgInfo(XbdunSysOrgDo xbdunSysOrgDo,Client client)throws RuntimeException{
		Map<String,Object> param = new HashMap<String,Object>();
		
		if (SysOrgAuditingStatusEnum.isKey(xbdunSysOrgDo.getAuditingStatus())) {// 审核状态
			param.put("auditingStatus", xbdunSysOrgDo.getAuditingStatus());
			param.put("auditingTime", new Date());
			
			if (xbdunSysOrgDo.getOrgCode() == SysOrgConst.INIT_ORG_CODE && xbdunSysOrgDo.getAuditingStatus() == SysOrgAuditingStatusEnum.PASS.getKey()) {// 企业编码为0并且审核通过, 审核之后给企业编码
				// 获取企业编码
				Long orgCode = sysOrgMapper.getMaxOrgCode();
				if (xbdunSysOrgDo.getOrgCode() == 0 && orgCode == 1) orgCode = SysOrgConst.DEFAULT_ORG_CODE;
				param.put("orgCode", orgCode);
			}
		}
		
		if (SysOrgEnableEnum.isKey(xbdunSysOrgDo.getEnable())) {// 停用/启用
			param.put("enable", xbdunSysOrgDo.getEnable());
			param.put("auditingTime", new Date());
		}
		
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getOrgName())) {// 修改企业名称
			param.put("orgName", xbdunSysOrgDo.getOrgName());
		}
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getWebsite())) {// 修改企业网站
			param.put("website", xbdunSysOrgDo.getWebsite());
		}
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getAddr())) {// 修改企业地址
			param.put("addr", xbdunSysOrgDo.getAddr());
		}
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getLogo())) {// 修改企业LOGO
			param.put("logo", xbdunSysOrgDo.getLogo());
		}
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getRecordImg())) {// 修改企业备案照片
			param.put("recordImg", xbdunSysOrgDo.getRecordImg());
		}
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getRecordNo())) {// 修改企业备案号
			param.put("recordNo", xbdunSysOrgDo.getRecordNo());
		}
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getRemarks())) {// 修改备注
			param.put("remarks", xbdunSysOrgDo.getRemarks());
		}
		if (0 != xbdunSysOrgDo.getLimitPers()) {// 修改企业上限人数
			param.put("limitPers", xbdunSysOrgDo.getLimitPers());
		}
		
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getOrgMobile())) {// 修改企业电话
			param.put("orgMobile", xbdunSysOrgDo.getOrgMobile());
		}
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getOrgLandline())) {// 修改企业座机
			param.put("orgLandline", xbdunSysOrgDo.getOrgLandline());
		}
		if (StringUtils.isNotBlank(xbdunSysOrgDo.getOrgEmail())) {// 修改企业邮箱
			param.put("orgEmail", xbdunSysOrgDo.getOrgEmail());
		}
		
		Timestamp version = sysOrgMapper.getSysOrgVersion(xbdunSysOrgDo.getId());
		if(null==version){
			throw BizException.DB_SELECTONE_IS_NULL.newInstance("没能查询到对应的机构");
		}
		
		Map<String,Object> where = new HashMap<String,Object>();
		where.put("id", xbdunSysOrgDo.getId());
		where.put("version", version);
		
		//更新数据
		if(0==sysOrgMapper.updateDynXbdunSysOrg(param, where)){
			param.clear();
			where.clear();
			param = null;
			where = null;
			throw BizException.DB_UPDATE_RESULT_0;
		}
		param.clear();
		where.clear();
		param = null;
		where = null;
	}
	
	/**
	 * 查询分页
	 * @param where			约束条件,键是对象属性其中条件都为and连接
	 * @param orderBy		排序条件
	 * @param pageNum   	当前索引页
	 * @param numPerPage	每页显示条数
	 * @return
	 * @throws RuntimeException
	 */
	public Pager<SysOrgResponse> queryPager(Map<String,Object> where,String orderBy,int pageIndex,int pageSize){
		log.info("机构分页查询，{}",where);
		//分页对象
		Pager<SysOrgResponse> resultPager = new Pager<SysOrgResponse>();
		
		resultPager.setPageSize(pageSize);
		resultPager.setPageIndex(pageIndex);
		
		Long resultCnt = sysOrgMapper.queryPagerCount(where);
		if(null!=resultCnt&&resultCnt.longValue()==0){
			
			resultPager.setTotalCount(0);
			return resultPager;
		}
		
		//获取查询结果集List
		List<XbdunSysOrgDo> list = sysOrgMapper.queryPager(where, orderBy,(resultPager.getPageIndex()-1)*resultPager.getPageSize(), resultPager.getPageSize());
		if(!CollectionUtils.isEmpty(list)){
			resultPager.setData(new ArrayList<SysOrgResponse>());
			SysOrgResponse infoRes = null;
			try{
				for(XbdunSysOrgDo info : list){
					infoRes = new SysOrgResponse();
					//复制企业列表信息
					BeanUtils.copyProperties(infoRes, info);
					resultPager.getData().add(infoRes);
				}
			}catch(Exception e){
				log.error("企业信息查询组合list异常",e);
			}finally{
				list.clear();
				list = null;
			}
		}
		//设置查询条数
		resultPager.setTotalCount(resultCnt.longValue());
		resultPager.setPager();
		return resultPager;
	}

	public int existSysOrg(XbdunSysOrgDo xbdunSysOrgDo)throws RuntimeException{
		Assert.notNull(xbdunSysOrgDo,"xbdunSysOrgDo对象不能为Null");
		if(StringUtils.isBlank(xbdunSysOrgDo.getOrgName())&&StringUtils.isBlank(xbdunSysOrgDo.getOrgEmail())&&StringUtils.isBlank(xbdunSysOrgDo.getRecordNo())){
			throw BizException.PARAM_CHKE_FAIL.newInstance("企业名称/企业email/备案号不能同时为空");
		}
		return sysOrgMapper.existSysOrg(xbdunSysOrgDo);
	}
	
	/**
	* @Title: modifyAgentOrg
	* @Description: 设置代理机构,前提机构必须是已经通过了审核才能够设置
	* @param orgCode		  机构编号
	* @param blAgentOrg		 是否代理	是【1】，不是【2】
	* @throws BizException    异常
	* @return void    返回类型
	 */
	public void modifyAgentOrg(long orgCode,int blAgentOrg)throws RuntimeException{
		//如果设置为代理，但是实际上系统已经存在了
		if(YesOrNoEnum.YES.getKey()==blAgentOrg&&null!=sysOrgMapper.getAgentOrgCode()){
			throw BmpBizException.AGENT_ORG_EXSIT;
		}
		Timestamp version = sysOrgMapper.getVersionByCode(orgCode);
		if(null == version){
			throw BizException.DB_SELECTONE_IS_NULL.newInstance("机构不存在");
		}
		//获取机构负责人
		if(0==sysOrgMapper.uptAgentOrg(orgCode, blAgentOrg,version)){
			throw BizException.DB_UPDATE_RESULT_0.newInstance("设置代理机构失败,如果多次设置都失败，请取消其他代理机构然后重新设置");
		}
		if(sysOrgMapper.getAgentOrgCodeCnt()>1){
			throw BizException.DB_UPDATE_RESULT_0.newInstance("由于系统访问繁忙，请重新在试一次");
		}
		AgentOrgDto oldAgent = orgUserMapper.getOldXbdOrgUser();
		if(null == oldAgent){
			throw BizException.DB_SELECTONE_IS_NULL.newInstance("从前的老机构平台用户不存在");
		}
		//是代理机构
		if(YesOrNoEnum.YES.getKey()==blAgentOrg){
			//将从前的平台管理员修改为超级管理员
			if(0==orgUserMapper.setOldAgentOrgUser(oldAgent.getUserId(),oldAgent.getVersion())){
				throw BizException.DB_SELECTONE_IS_NULL.newInstance("修改平台管理员角色失败");
			}
			//查询机构他的超级管理员或者超级管理员+管理员
			Map<String,Object> versionByCode = orgUserMapper.selectSuperAdmin(orgCode);
			if(null == versionByCode||versionByCode.isEmpty()){
				throw BizException.DB_SELECTONE_IS_NULL.newInstance("新机构没有管理员存在");
			}
			//更换为新的平台管理员
			if(0==orgUserMapper.setAgentOrgUser((Timestamp)versionByCode.get("version"),(String)versionByCode.get("userId"),(Integer)versionByCode.get("specilRole"))){
				throw BizException.DB_UPDATE_RESULT_0.newInstance("设置代理机构用户失败，请稍后再试...");
			}
		}else{
			AgentOrgDto oldXbdun = orgUserMapper.getOldXbdunRole();
			if(null != oldXbdun){
				//机构是否与取消的机构相同
				if(orgCode!=oldAgent.getOrgCode()){
					throw BizException.DB_UPDATE_RESULT_0.newInstance("平台代理机构并非自己，平台逻辑错误，请联系管理员");
				}
				//取消当前的机构，还原角色
				if(0==orgUserMapper.restoreRole(oldAgent.getUserId(),oldAgent.getOldSpecilRole(),oldAgent.getVersion())){
					throw BizException.DB_UPDATE_RESULT_0.newInstance("取消代理机构，还原角色失败");
				}
				oldAgent = null;
				//还原从前老平台角色
				//还原从前老的平台管理员
				if(0==orgUserMapper.restoreRole(oldXbdun.getUserId(),UserRolesEnums.XBDADMINT.getKey(),oldXbdun.getVersion())){
					throw BizException.DB_SELECTONE_IS_NULL.newInstance("还原平台管理员失败");
				}
				//获取机构
				orgCode = oldXbdun.getOrgCode();
			}
		}
		//加入用户当前机构
		if(orgUserBiz.cachePutXbdunOrgCode()!=orgCode){
			throw BizException.DB_UPDATE_RESULT_0.newInstance("设置代理机构用户失败，请稍后再试...");
		}
	}

	/***获取代理机构*/
	public Long getAgentOrgCode()  throws Exception{
		return sysOrgMapper.getAgentOrgCode();
	}

	/****获取机构信息*****/
	public XbdunSysOrgDo getOrgById(long id)  throws Exception{
		return sysOrgMapper.getOrgById(id);
	}

	public long auditingSysOrg(XbdunSysOrgDo xbdunSysOrgDo, Client client) throws Exception {
		//获取当前企业的企业法人
		XbdunSysUserDo sysUserDo = sysUserMapper.getByUnionId(xbdunSysOrgDo.getUnionid());
		if(sysUserDo == null){
			throw BizException.DB_SELECTONE_IS_NULL.newInstance("当前企业没有企业法人");
		}
		
		Map<String,Object> param = new HashMap<String,Object>();
		param.put("userCode", sysUserDo.getUserCode());
		param.put("auditingStatus", xbdunSysOrgDo.getAuditingStatus());
		param.put("remarks", xbdunSysOrgDo.getRemarks());
		param.put("auditingTime", new Date());
		Long orgCode = null;
		if (xbdunSysOrgDo.getOrgCode() == SysOrgConst.INIT_ORG_CODE && xbdunSysOrgDo.getAuditingStatus() == SysOrgAuditingStatusEnum.PASS.getKey()) {// 企业编码为0并且审核通过, 审核之后给企业编码
			// 获取企业编码
			orgCode = sysOrgMapper.getMaxOrgCode();
			if (xbdunSysOrgDo.getOrgCode() == 0 && orgCode == 1) orgCode = SysOrgConst.DEFAULT_ORG_CODE;
			param.put("orgCode", orgCode);
		}
		
		Timestamp version = sysOrgMapper.getSysOrgVersion(xbdunSysOrgDo.getId());
		if(null==version){
			throw BizException.DB_SELECTONE_IS_NULL.newInstance("没能查询到对应的机构");
		}
		
		Map<String,Object> where = new HashMap<String,Object>();
		where.put("id", xbdunSysOrgDo.getId());
		where.put("version", version);
		
		//更新机构数据
		if(0==sysOrgMapper.updateDynXbdunSysOrg(param, where)){
			param.clear();
			where.clear();
			param = null;
			where = null;
			throw BizException.DB_UPDATE_RESULT_0.newInstance("审核失败");
		}
		param.clear();
		where.clear();
		
		//为企业法人设置orgCode
		param.put("orgCode", orgCode);
		where.put("unionid", sysUserDo.getUnionid());
		where.put("version", sysUserDo.getVersion());
		if(0==sysUserMapper.updateDynXbdunSysUser(param, where)){
			param.clear();
			where.clear();
			param = null;
			where = null;
			throw BizException.DB_UPDATE_RESULT_0.newInstance("修改企业法人失败");
		}
		param = null;
		where = null;
		//删除机构编号
		orgInfoCacheService.removeSingleOrgInfo(orgCode);
		
		//将企业法人创建到机构用户中
		XbdunOrgUserDo orgUserDo = new XbdunOrgUserDo();
		orgUserDo.setOrgCode(orgCode);
		orgUserDo.setUserCode(sysUserDo.getUserCode());
		orgUserDo.setUserId(CommonUtil.generateOrgUserId(orgCode, sysUserDo.getUserCode()));
		orgUserDo.setRealName(sysUserDo.getRealName());
		orgUserDo.setState(UserEffectEnum.EFFECT.getKey());
		orgUserDo.setEnabled(UserEnabledEnum.ENABLED.getKey());
		orgUserDo.setInauType(UserInauTypeEnum.DEFAULT.getKey());
		orgUserDo.setSpecilRole(SpecilRoleEnum.SUPPERADMIN.getKey());
		orgUserDo.setInvitType(SysOrgInvitTypeEnum.UN_INVITATION.getKey());
		orgUserDo.setOrgEmail(sysUserDo.getEmail());
		orgUserDo.setMobile(sysUserDo.getMobile());
		orgUserDo.setCreateTime(new Date());
		
		Long orgUserId = orgUserMapper.addXbdunOrgUser(orgUserDo);
		if (orgUserId==null||orgUserId.longValue()<0) {
			throw BizException.DB_INSERT_RESULT_0.newInstance("创建机构用户失败");
		}
		
		return orgCode;
	}
	
}